package org.jeecg.common.wx;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.modules.wx.entity.WxAccount;
import org.jeecg.common.modules.wx.service.IWxAccountService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.weixin4j.loader.ITicketLoader;
import org.weixin4j.loader.ITokenLoader;
import org.weixin4j.model.base.Token;
import org.weixin4j.model.js.Ticket;
import org.weixin4j.model.js.TicketType;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

/**
 * @author guoyh
 * @ClassName AccessTokenImpl
 * @Description
 * @since 2020/8/13 23:04
 **/
@Component
@Slf4j
public class AccessTokenImpl implements ITokenLoader , ITicketLoader {

    @Resource
    private IWxAccountService wxAccountService;

    private static final String OPERATOR = "REFRESH_ACCESS_TOKEN";

    private static final long EX_TIME = 5400000L;

    @Value("${weixin4j.config.appid}")
    private String appid;
    @Override
    public Token get() {
        WxAccount wxAccount = getByAppid(appid);
        if (overduce(wxAccount.getAddTokenTime())){
            return null;
        }
        Token token = new Token(wxAccount.getAccessToken(),wxAccount.getExpiresIn(),wxAccount.getAddTokenTime().getTime());
        return token;
    }

    @Override
    public void refresh(Token token) {
        WxAccount wxAccount = getByAppid(appid);
        wxAccount.setAccessToken(token.getAccess_token());
        wxAccount.setAddTokenTime(new Date(token.getCreate_time()));
        wxAccount.setUpdateBy(OPERATOR);
        wxAccount.setUpdateTime(new Date());
        wxAccountService.updateById(wxAccount);
    }

    private WxAccount getByAppid(String appid){
        LambdaQueryWrapper<WxAccount> query = Wrappers.lambdaQuery();
        query.eq(WxAccount::getAppid,appid);
        return wxAccountService.getOne(query);
    }

    @Override
    public Ticket get(TicketType ticketType) {
        if (Objects.equals(ticketType,TicketType.WX_CARD)){
            throw new RuntimeException("api not impl");
        }
        WxAccount wxAccount = getByAppid(appid);
        if (overduce(wxAccount.getAddTicketTime())){
            return null;
        }
        return new Ticket(TicketType.JSAPI,wxAccount.getJsTicket(),wxAccount.getExpiresIn(),wxAccount.getAddTicketTime().getTime());
    }

    @Override
    public void refresh(Ticket ticket) {
        if (Objects.equals(ticket.getTicketType(),TicketType.WX_CARD)){
            throw new RuntimeException("api not impl");
        }
        WxAccount wxAccount = getByAppid(appid);
        wxAccount.setJsTicket(ticket.getTicket());
        wxAccount.setAddTicketTime(new Date(ticket.getCreate_time()));
        wxAccount.setUpdateBy(OPERATOR);
        wxAccount.setUpdateTime(new Date());
        wxAccountService.updateById(wxAccount);
    }

    private boolean overduce(Date addTime){
        long createTime = addTime.getTime();
        long now = System.currentTimeMillis();
        return now - createTime > EX_TIME;
    }
}
